﻿using RQX.Common.Core.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace RQX.Common.Core.Hardware.Net
{
    public class UdpSocket
    {
        #region Init
        private readonly string _ip;
        private readonly int _port;
        private readonly int _port_local;
        private IPEndPoint _iep;
        private readonly UdpClient _client;
        private Action<byte[]> _recv_action;

        public UdpSocket(UdpSocket source) : this(source._ip, source._port, source._port_local)
        {
            _recv_action = source._recv_action;
            BuildRecvHandler();
        }
        public UdpSocket(int localPort) : this(null, 0, localPort) { }
        public UdpSocket(string ip, int port) : this(ip, port, 0) { }

        public UdpSocket(string ip, int port, int localPort)
        {
            _ip = ip;
            _port = port;
            _port_local = localPort;

            if (_port_local != 0)
            {
                _client = new UdpClient(_port_local);
            }
            if (_ip.IsNotNullOrEmpty() && _port != 0)
            {
                _iep = new IPEndPoint(IPAddress.Parse(_ip), _port);
                if(_client == null)
                {
                    _client = new UdpClient(_ip, _port);
                }
                else
                {
                    _client.Connect(_iep);
                }
            }
            if(_client == null) throw new Exception("初始化参数异常！");
        }
        #endregion

        #region 对外接口
        /// <summary>
        /// 关闭UDP
        /// </summary>
        public void Close()
        {
            _client.Close();
        }
        /// <summary>
        /// 绑定接收函数
        /// </summary>
        /// <param name="RecvAction"></param>
        public void BindRecvHandler(Action<byte[]> RecvAction)
        {
            _recv_action = RecvAction;
            BuildRecvHandler();
        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="buffer"></param>
        public void Send(byte[] buffer)
        {
            if (_iep != null)
            {
                _client.Send(buffer, buffer.Length, _iep);
            }
        }
        #endregion

        #region private

        private void BuildRecvHandler()
        {
            var buffer = _client.Receive(ref _iep);
            _recv_action(buffer);
        }
        #endregion
    }
}
